/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */
package com.ykht.proj.activity.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ykht.proj.activity.dto.CnActivityConsumeExportReq;
import com.ykht.proj.activity.dto.CnActivityConsumeRecordDTO;
import com.ykht.proj.activity.entity.CnActivityConsumeRecord;
import com.ykht.proj.activity.entity.CnActivityOrder;
import com.ykht.proj.activity.entity.CnActivityPersonShop;
import com.ykht.proj.activity.mapper.CnActivityConsumeRecordMapper;
import com.ykht.proj.activity.service.CnActivityConsumeRecordService;
import com.ykht.proj.activity.service.CnActivityPersonShopService;
import com.ykht.proj.admin.api.entity.SysUser;
import com.ykht.proj.admin.api.feign.RemoteUserService;
import com.ykht.proj.admin.api.vo.UserVO;
import com.ykht.proj.common.core.constant.CommonConstants;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.Enum.UserTypeEnum;
import com.ykht.proj.coupon.api.feign.RemoteShopService;
import com.ykht.proj.coupon.api.feign.RemoteWaiterExtService;
import com.ykht.proj.coupon.entity.CnShop;
import com.ykht.proj.coupon.entity.FxWaiterExt;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 核销表（消费记录表）
 *
 * @author csg
 * @date 2020-12-23 11:13:32
 */
@Service
public class CnActivityConsumeRecordServiceImpl extends ServiceImpl<CnActivityConsumeRecordMapper, CnActivityConsumeRecord> implements CnActivityConsumeRecordService {
	@Resource
	private CnActivityConsumeRecordMapper cnActivityConsumeRecordMapper;

	@Resource
	private RemoteShopService remoteShopService;
	@Resource
	private RemoteUserService remoteUserService;
	@Resource
	private CnActivityPersonShopService cnActivityPersonShopService;
	@Resource
	private RemoteWaiterExtService remoteWaiterExtService;

	/**
	 * 消费记录列表（分页，搜索）
	 *
	 * @param page
	 * @param req
	 * @return
	 */
	@Override
	public IPage<CnActivityConsumeRecordDTO> getCnActivityConsumeRecordListPage(Page page, CnActivityConsumeRecordDTO req) {
		IPage<CnActivityConsumeRecordDTO> tempPage = cnActivityConsumeRecordMapper.getCnActivityConsumeRecordListPage(page, req);
		List<CnActivityConsumeRecordDTO> list = tempPage.getRecords();

		if (list.size()==0) return tempPage;

		List<Long> waiterIds = new ArrayList<>();//服务员登录人id
		List<Long> shopIds = new ArrayList<>();//门店登录人id
		list.stream().filter(o->null!=o.getVerificationType()).forEach(o->{
			if (o.getVerificationType()==1) waiterIds.add(o.getCreateUser());
			else if(o.getVerificationType()==2) shopIds.add(o.getCreateUser());
		});

		if (waiterIds.size()+shopIds.size()==0) return tempPage;

		if (waiterIds.size()>0){
			R<List<SysUser>> r = remoteUserService.getUserByIds(waiterIds);
			if (r.getCode()== CommonConstants.SUCCESS){
				list.stream().forEach(o->{
					r.getData().stream().forEach(user->{
						if (o.getCreateUser().intValue()==user.getUserId()) o.setUserName(user.getNickName());
					});
				});
			}
		}
		if (shopIds.size()>0){
			R<List<SysUser>> r = remoteUserService.getUserByIds(shopIds);
			if (r.getCode()== CommonConstants.SUCCESS){
				list.stream().forEach(o->{
					r.getData().stream().forEach(user->{
						if (o.getCreateUser().intValue()==user.getUserId()) o.setUserName(user.getUsername());
					});
				});
			}
		}
		return tempPage;
	}

	/**
	 * 根据ID 获取消费记录详情
	 *
	 * @param id
	 * @return
	 */
	@Override
	public CnActivityConsumeRecordDTO getByIdCnActivityConsumeRecord(Long id) {
		CnActivityConsumeRecordDTO o = cnActivityConsumeRecordMapper.getByIdCnActivityConsumeRecord(id);
		UserVO vo = remoteUserService.getByIdUser(o.getCreateUser());
		if (vo!=null){
			if (o.getVerificationType()==1) o.setUserName(vo.getNickName());//服务员
			else if(o.getVerificationType()==2) o.setUserName(vo.getUsername());//门店
		}
		return o;
	}

	/**
	 * 下载搜索 核销表（消费记录表）数据
	 *
	 * @param req
	 */
	@Override
	public void downloadExcel(CnActivityConsumeRecordDTO req) {
		// 获取满足条件的导出数据
		Page<CnActivityOrder> page = new Page();
		page.setSize(999999);
		IPage<CnActivityConsumeRecordDTO> recordListPage = cnActivityConsumeRecordMapper.getCnActivityConsumeRecordListPage(page, req);
		List<CnActivityConsumeExportReq> bean = new ArrayList<>();
		// 日期转换
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		recordListPage.getRecords().stream().forEach(itme -> {
			if (null != itme.getPayTime()) {
				itme.setPayTimeShow(dateTimeFormatter.format(itme.getPayTime()));
			}
			bean.add(BeanUtil.toBean(itme, CnActivityConsumeExportReq.class));
		});
		ExcelWriter writer = null;
		ServletOutputStream out = null;
		HttpServletResponse response = null;
		try {
			writer = ExcelUtil.getWriter(true);
			response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
			//自定义标题名
			writer.addHeaderAlias("id", "排序");
			writer.addHeaderAlias("userPhone", "用户账号");
			writer.addHeaderAlias("activityName", "产品名称");
			writer.addHeaderAlias("consumptionAmount", "消费金额");
			writer.addHeaderAlias("payAmount", "应付金额");
			writer.addHeaderAlias("shopName", "消费商家");
			writer.addHeaderAlias("payTimeShow", "消费时间");

			// 一次性写出内容，使用默认样式，强制输出标题
			writer.write(bean, true);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");
			//这里容易乱码 处理
			String name = "消费列表";
			name = URLEncoder.encode(name, "UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + name + ".xls");
			out = response.getOutputStream();
			writer.flush(out, true);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭writer
			writer.close();
		}
		//关闭输出Servlet流
		IoUtil.close(out);
	}

	/**
	 * 添加消费记录  并修改消费次数
	 *
	 * @param activityConsumeRecord
	 * @return
	 */
	@Override
	public CnActivityConsumeRecordDTO addCnActivityConsumeRecord(CnActivityConsumeRecord activityConsumeRecord) {
		Integer userType = SecurityUtils.getUser().getUserType();
		CnShop shop = null;
		if (UserTypeEnum.WAITER.getValue().equals(userType)){
			FxWaiterExt userExt = remoteWaiterExtService.getUserExt();
			shop = remoteShopService.getById(userExt.getShopId());
		} else {
			shop = remoteShopService.getByLoginIdShop();
		}
		activityConsumeRecord.setShopId(shop.getId());
		activityConsumeRecord.setShopName(shop.getName());
		this.save(activityConsumeRecord);
		// 修改使用次数
		CnActivityPersonShop personShop = cnActivityPersonShopService.getOne(new QueryWrapper<CnActivityPersonShop>().lambda()
				.eq(CnActivityPersonShop::getOrderId, activityConsumeRecord.getOrderId())
				.eq(CnActivityPersonShop::getPerId, activityConsumeRecord.getPersonId())
				.eq(CnActivityPersonShop::getShopId, shop.getId()));
		if (personShop.getUsageTimes() == 1){
			personShop.setEndTime(LocalDateTime.now());
		}
		personShop.setUsageTimes(personShop.getUsageTimes() - 1);
		personShop.setUpdateTime(LocalDateTime.now());
		cnActivityPersonShopService.updateById(personShop);
		return getByIdCnActivityConsumeRecord(activityConsumeRecord.getId());
	}
}
